package com.unis.controller;

import com.unis.common.exception.http.NotFoundException;
import com.unis.common.secure.authc.AccountLoginToken;
import com.unis.common.secure.authc.UserInfo;
import com.unis.logger.TargetLogger;
import com.unis.model.system.Permission;
import com.unis.model.system.Role;
import com.unis.service.system.PermissionService;
import com.unis.service.system.RoleService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * Created by Administrator on 2018/12/27/027.
 */
@Controller
public class DefaultController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(DefaultController.class);

    @Autowired
    private  RoleService roleService;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private DefaultWebSessionManager sessionManager;


    @RequestMapping("/login")
    public String loginForm(HttpServletRequest request) throws Exception {
        String forword="login";

        return forword;
    }

    @RequestMapping("/errors/404")
    public void handleNotFoundRequest() {
        throw new NotFoundException("请求未发现!");
    }


    /**
     * <p>
     * 处理登录请求
     * </p>
     *
     * @param user
     * @return
     * @throws Exception
     */
    @TargetLogger("0101")
    @RequestMapping(value = "/authenticate", method = RequestMethod.POST)
    public String handleLoginSubmitRequest(UserInfo user, RedirectAttributes redirectAttributes, HttpSession httpSession) throws Exception{
        String forword = "redirect:/login";

        if (user!=null && StringUtils.isNotBlank(user.getPassword()) && StringUtils.isNotBlank(user.getUsername())){
            AccountLoginToken token = new AccountLoginToken(user.getUsername(),user.getPassword(),user);
            token.setRememberMe(user.getRemeberMe());
            Subject subject = SecurityUtils.getSubject();
            try{
                subject.login(token);
                //forword = "redirect:/index/indexPage";
                UserInfo userInfo = (UserInfo) subject.getPrincipal();
                Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();
                for (Session session : sessions) {
                    if (session.getTimeout() > 0
                            && userInfo.getPk().equals(
                            String.valueOf(session.getAttribute("userpk")))
                            && !session.getAttribute("sessionid").equals(
                            subject.getSession().getId())) {
                        session.setTimeout(0);
                        httpSession.setAttribute("sfbtc", "Y");//用户已登录，标记踢出
                        break;
                    }
                }
                subject.getSession().setAttribute("sessionid", subject.getSession().getId());
                subject.getSession().setAttribute("userpk", userInfo.getPk());

                Set<String> roles = new HashSet<String>();
                Set<String> permissions = new HashSet<String>();

                List<Role> roleList = roleService.queryCurrentUserRole(userInfo.getPk());

                if (roleList!=null && roleList.size()>0){
                    for (Role role : roleList){
                        roles.add(role.getCode());
                    }
                    userInfo.setRoleCodeSet(roles);
                }

                List<Permission> permissionList = permissionService.queryCurrentUserPermit(userInfo.getPk());
                if(permissionList!=null && permissionList.size()>0){
                    for (Permission permission : permissionList){
                        permissions.add(permission.getCode());
                    }
                    userInfo.setPermissionCodeSet(permissions);
                }


                /*特殊权限进入特殊首页
                if (userInfo.getRoleCodeSet().toString().indexOf("jsdhyjzy") != -1) {
                    forword = "redirect:/voip/fdzptYjxx/page.html";
                }*/
                /*httpSession.setAttribute("xm", userInfo.getXm());
                httpSession.setAttribute("sfzh", userInfo.getIdno());
                httpSession.setAttribute("jh", userInfo.getJh());
                httpSession.setAttribute("jgmc", userInfo.getJgmc());
                httpSession.setAttribute("jgdm", userInfo.getJgdm());
                httpSession.setAttribute("jsdm", roles.toString());
                httpSession.setAttribute("qxdm", permissions.toString());
                httpSession.setAttribute("ywsjdm", userInfo.getDept().getYwsjdm());*/

                //获取用户权限对应菜单
                forword = "redirect:/index";
            } catch (UnknownAccountException uae) {
                logger.error(uae.getMessage());// username wasn't in the system
                redirectAttributes.addFlashAttribute(REMIND_MSG, "用户不存在!");
            } catch (IncorrectCredentialsException ice) {
                logger.error(ice.getMessage());// password didn't match
                redirectAttributes.addFlashAttribute(REMIND_MSG, "密码不正确!");
            } catch (LockedAccountException lae) {
                logger.error(lae.getMessage());// account for user is locked
                redirectAttributes.addFlashAttribute(REMIND_MSG, "账户被锁定!");
            } catch (ExcessiveAttemptsException eae) {
                logger.error(eae.getMessage());// try times exclude
                redirectAttributes.addFlashAttribute(REMIND_MSG, "密码尝试限制!");
            } catch (AuthenticationException e) {
                logger.error(e.getMessage());
                String msg = "";
                if (StringUtils.startsWith(e.getMessage(),"用户已过期") || StringUtils.startsWith(e.getMessage(),"未发现用户")){
                    msg = e.getMessage();
                }
                redirectAttributes.addFlashAttribute(REMIND_MSG, "认证登录失败!"+msg);
            } catch (Exception e) {
                logger.error(e.getMessage());
                redirectAttributes.addFlashAttribute(REMIND_MSG, "认证失败!");
            }
        }else {
            logger.error("用户名/密码为空");
            redirectAttributes.addFlashAttribute(REMIND_MSG, "用户名/密码为空!");
        }

        return forword;
    }
    @RequestMapping("/index")
    public String forwordIndex(ModelMap map) throws Exception {
        String forword="index";

        return forword;
    }

    /**
     * 注销退出系统
     *
     * @return
     */
    @TargetLogger("0102")
    @RequestMapping("/logout")
    public String logout() {
        String forword = "redirect:/login";
        Subject currentUser = SecurityUtils.getSubject();
        if (currentUser != null && currentUser.getSession() != null) {
            currentUser.logout();
        }
        return forword;
    }

}
